package com.yix.admin.modules.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.yix.admin.modules.system.entity.SysDict;
import com.yix.admin.modules.system.entity.dto.SysDictDetailDto;
import com.yix.admin.modules.system.entity.dto.SysDictDto;
import com.yix.admin.modules.system.entity.mapper.SysDictMapper;
import com.yix.admin.modules.system.entity.query.SysDictQuery;
import com.yix.admin.modules.system.repository.SysDictRepository;
import com.yix.admin.modules.system.service.SysDictService;
import com.yix.common.utils.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * @author wdx
 * @version 1.0
 * @Description TODO
 * @date 2021/2/5 13:56
 */
@Service
@CacheConfig(cacheNames = "dict")
public class SysDictServiceImpl implements SysDictService {

    @Autowired
    private SysDictRepository sysDictRepository;
    @Autowired
    private SysDictMapper sysDictMapper;
    @Autowired
    private RedisUtils redisUtils;

    @Override
    public List<SysDictDto> queryAll(SysDictQuery dict) {
        List<SysDict> list = sysDictRepository.findAll((root, query, cb) -> QueryHelp.getPredicate(root, dict, cb));
        return sysDictMapper.toDto(list);
    }

    @Override
    public Map<String, Object> queryAll(SysDictQuery dict, Pageable pageable){
        Page<SysDict> page = sysDictRepository.findAll((root, query, cb) -> QueryHelp.getPredicate(root, dict, cb), pageable);
        return PageUtil.toPage(page.map(sysDictMapper::toDto));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(SysDict resources) {
        resources.setCreaterId(SecurityUtils.getCurrentUserId());
        sysDictRepository.save(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysDict resources) {
        // 清理缓存
        delCaches(resources);
        SysDict dict = sysDictRepository.findById(resources.getId()).orElseGet(SysDict::new);
        ValidationUtil.isNull( dict.getId(),"Dict","id",resources.getId());
        resources.setId(dict.getId());
        resources.setUpdaterId(SecurityUtils.getCurrentUserId());
        sysDictRepository.save(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Set<Long> ids) {
        // 清理缓存
        List<SysDict> dicts = sysDictRepository.findByIdIn(ids);
        for (SysDict dict : dicts) {
            delCaches(dict);
        }
        sysDictRepository.deleteByIdIn(ids);
    }

    @Override
    public void download(List<SysDictDto> dictDtos, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (SysDictDto dictDTO : dictDtos) {
            if(CollectionUtil.isNotEmpty(dictDTO.getDictDetails())){
                for (SysDictDetailDto dictDetail : dictDTO.getDictDetails()) {
                    Map<String,Object> map = new LinkedHashMap<>();
                    map.put("字典名称", dictDTO.getName());
                    map.put("字典描述", dictDTO.getDescription());
                    map.put("字典标签", dictDetail.getLabel());
                    map.put("字典值", dictDetail.getValue());
                    map.put("创建日期", dictDetail.getCreateTime());
                    list.add(map);
                }
            } else {
                Map<String,Object> map = new LinkedHashMap<>();
                map.put("字典名称", dictDTO.getName());
                map.put("字典描述", dictDTO.getDescription());
                map.put("字典标签", null);
                map.put("字典值", null);
                map.put("创建日期", dictDTO.getCreateTime());
                list.add(map);
            }
        }
        FileUtil.downloadExcel(list, response);
    }

    public void delCaches(SysDict dict){
        redisUtils.del(CacheKey.DICT_NAME + dict.getName());
    }
}
